﻿//主界面
package com.victim.snake.graphics
{
	import flash.display.Sprite;
	import com.victim.snake.user.User;
	import flash.events.Event;
	import com.victim.snake.snake.Snake;
	import com.victim.snake.snake.Body;
	import flash.events.KeyboardEvent;
	import flash.utils.ByteArray;
	import com.victim.snake.user.ProcessMsg;
	import flash.text.TextField;
	import com.victim.snake.snake.Food;
	import com.victim.snake.graphics.mainClass.GrayTranDiv;
	import com.victim.snake.snake.SnakeStyle;
	import flash.utils.*;
	
	
	//游戏界面
	public class PlaySprite extends Sprite
	{
		public var snakeGraphics:SnakeGraphics= new SnakeGraphics();	//创建画布
		var snake:Snake=null;	//当前用户的蛇
		var textFiled:TextField=new TextField();
		var num:int=0;	//帧频计数器
		var keyCodeArray:Array=new Array();	//转向数组
		//var foodArray:Array=new Array(); 	//食物
		
		var t:uint=0;	//用于关闭指定间隔运行的函数
		
		//构造函数
		public function PlaySprite(){
			snake=User.getSnake();	//当前用户的蛇,供改变方向回调函数使用
			snakeGraphics.setSnakesDictionary(User.getRoom().getSnakes());	//添加蛇列表
			
			
			//如果游戏资源下载完成，发送就绪消息
			t=setInterval(isLoader,10);
			
			//测试用
			textFiled.width=800;
			this.addChildAt(textFiled,this.numChildren);			
			//测试代码结束
		}
		
		//设置当前玩家的蛇（当当前玩家蛇死亡并重新复活时调用）
		public function setSnake():void{
			this.snake=User.getSnake();
		}
		
		public function isLoader():void{
			//trace("判断下载");
			//判断
			var loaderAll:Boolean=true;
			
			//添加背景
			if(User.getRoom().getMap().isLoader()){
				this.addChild(User.getRoom().getMap().getBackGroundImage());
			}else{
				loaderAll=false;
			}
			
			
			//如果蛇皮肤没下载完
			for each(var snakeStyle:SnakeStyle in SnakeStyle.snakeStyles){					
				if(!snakeStyle.isAllLoad()){
					loaderAll=false;
				}
			}
			
			//如果下载完成，发送就绪消息
			if(loaderAll){
				//trace("下载完成");
				clearInterval(t);	//停止判断
				var readByte:ByteArray=new ByteArray();
				readByte.writeByte(9);	//就绪论消息
				readByte.writeShort(0);	//消息内容的长度
				ProcessMsg.socketSend(readByte);
			}
		}
		
		public function setText(info:String):void{
			this.textFiled.text=info;
		}
		
		
		
		public function getText():String{
			return this.textFiled.text;
		}
		
		//添加食物
		public function addFood(id:int,type:uint,x:uint,y:uint,width:Number,height:Number){
			this.snakeGraphics.addFood(new Food(id,type,x,y,width,height));
		}
		
		//删除食物
		public function removeFood(id:int){
			this.snakeGraphics.removeFood(id);
		}
		
		//开始
		public function start():void{
			//每帧刷新画面移动蛇
			User.getStage().frameRate=36;	//设置帧频
			User.getStage().addEventListener(Event.ENTER_FRAME,entherFrame);	//添加事件
			//控制蛇上下左右按钮事件
			User.getStage().addEventListener(KeyboardEvent.KEY_DOWN, ctrSnake);
			User.getStage().focus=User.getStage();			
			
		}
		
		
		
		//键盘事件回调方法,上下左右控制蛇
		function ctrSnake(event:KeyboardEvent):void
		{	
			var keyCode:uint=event.keyCode;
			//trace(keyCode);
			//如果按的是上下左右键,
			if((keyCode>=37 && keyCode<=40) || keyCode==User.getPlayer().goLeftKeyCode || keyCode==User.getPlayer().goRightKeyCode ){
				
				//左右按键换为上下左右键
				var dire:uint=User.getSnake().getHead().getDirection();	//当前蛇方向
				switch(keyCode){
					case User.getPlayer().goLeftKeyCode :
						switch(dire){
							case 37:
								keyCode=40;
								break;
							case 38:
								keyCode=37;
								break;
							case 39:
								keyCode=40;
								break;
							case 40:
								keyCode=37;
								break;
						}
						break;
					case User.getPlayer().goRightKeyCode :
						switch(dire){
							case 37:
								keyCode=38;
								break;
							case 38:
								keyCode=39;
								break;
							case 39:
								keyCode=38;
								break;
							case 40:
								keyCode=39;
								break;
						}
						break;
				}
				
				//如果转向方向不等于原方向
				if(keyCode!=dire){
					this.keyCodeArray.push(keyCode);	//将转向添加到转向数组
				}

			}
				
		}
		
		//帧频事件回调方法
		function entherFrame(e:Event):void
		{	
			//测试信息重置
			//this.setText("1111");
			
			//帧频计数器
			num+=1;

			for each(var i:Snake in User.getRoom().getSnakes()){
				if(i!=null){
					//如果蛇接收帧频移动事件
					if(!i.getDeath()&&i.getEnterFrameMove()){
						if(num%i.getSpeed()==0){	//是否移动蛇
							//如果是当前玩家蛇
							if(i==this.snake ){
								this.eatFood(i);	//是否吃食物操作
								//如果转向数组有转向
								if(this.keyCodeArray.length>0){
									var keyCode:uint=this.keyCodeArray.shift();	//下一转向值
									//如果转向值合理
									if(i.isEffectiveDirection(keyCode)){
										//测试
										//this.setText(i.getX()+"  "+ i.getY()+"  "+keyCode);										
										//结束测试
										
										//上传转向消息给服务器
										var bytes:ByteArray=ProcessMsg.generateUTF8Msg(10,i.getId()+";"+i.getCoordinates()+keyCode);				
										//trace(i.getCoordinates());
										ProcessMsg.socketSend(bytes);
										//改变蛇方向
										i.setDirection(keyCode);	
										i.getHead().setIsTrun(true);
									}
								}
								
								
								//如果下一步移动不出界
								if(this.outOfBounds(i.getHead())){
									//蛇死亡
									i.setDeath(true);
									//this.snakeDeath();
									//蛇出界消息
									ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
									trace("撞墙死亡");
									
								}else if(this.isOverlappingSnake(i,i)){
									//撞到自己
									trace("玩家撞到自己");
									i.setDeath(true);
									ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
								}else if(this.isOverlappingUsers(i)){	//是否撞到其它玩家蛇
									trace(i.getName()+"撞到其它蛇");
									ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(16,i.getId()+";"+i.getCoordinates()+1+";"+num));	//(0为生，1为死亡									
								}else if(this.isOverlappingComputers(i)){	//如果撞到电脑蛇
									if(this.snake.getId()==User.getRoom().getMaster().getUid()){//如果是房主
										trace("房主撞到电脑");
										i.setDeath(true);
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
									}else{	//如果不是房主
										trace("非房主撞到电脑");
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(16,i.getId()+";"+i.getCoordinates()+1+";"+num));	//(0为生，1为死亡									
									}
								}
							}else{	//操做当前玩家蛇结束，操作其它蛇
								//房主操作电脑玩家
								if(i.getId()<0 && User.getRoom().getMaster().getUid()==User.getPlayer().getUid()){
									
									this.eatFood(i);	//吃食物
									
									//自动寻路,并生成转向消息发给服务器
									if(i.getHead().getDirection()!=i.autoSetDirection()){	
										var autoDireBytes:ByteArray=ProcessMsg.generateUTF8Msg(10,i.getId()+";"+i.getCoordinates()+i.getHead().getDirection());
										ProcessMsg.socketSend(autoDireBytes);
									}									
										
									//如果下一步出界
									if(this.outOfBounds(i.getHead())){
										trace("电脑出界");
										//蛇死亡
										i.setDeath(true);
										//上传蛇死亡消息
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
										
									}else if(this.isOverlappingUsers(i)){	//如果撞到其它蛇
										trace("电脑撞到其它蛇");
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(16,i.getId()+";"+i.getCoordinates()+1+";"+num));	//(0为生，1为死亡
									}else if(this.isOverlappingSnake(i,this.snake)){	//撞到当前玩家(房主)
										trace("电脑撞房主");
										i.setDeath(true);
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
									}else if(this.isOverlappingComputers(i)){	//撞到电脑
										trace("电脑撞到电脑");
										i.setDeath(true);
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(12,i.getId()+";"+i.getCoordinates()+1));	//(0为生，1为死亡
									}
									
								}else{//操作电脑蛇结束,操作非电脑其它蛇
									//如果当前移动的其它蛇撞到当前玩家
									if(this.isOverlappingSnake(i,User.getSnake())){
										trace("其它玩家撞到当前玩家");
										ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(16,i.getId()+";"+i.getCoordinates()+1+";"+num));	//(0为生，1为死亡
									}
									
									//如果是房主，判断当前移动的其它蛇是否撞到电脑
									if(this.snake.getId()==User.getRoom().getMaster().getUid()){//是否房主
										if(this.isOverlappingComputers(i)){
											trace("其它蛇撞到电脑");
											ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(16,i.getId()+";"+i.getCoordinates()+1+";"+num));	//(0为生，1为死亡
										}
									}
								}
							}	//操作其它蛇结束
							
							if(!i.getDeath()){
								i.moveByCoordinate();	//移动蛇
							}
							
						}	//移动蛇结束						
					}	//如果蛇接收帧频移动事件结束
				}	//如果蛇不为空
			}
			
			//在画布上画蛇
			snakeGraphics.draw();
			this.addChild(snakeGraphics.getGraphics());//将画布添加到主场景;	
	
		}		
		
		
		
		//吃到食物
		public function eatFood(snake:Snake):void{
			var body:Body=snake.getHead();
			for each(var food:Food in this.snakeGraphics.getFoods()){				
				if(isOverlappingXY(food.getX(),food.getY(),body.getX(),body.getY())){
					//吃食物
					ProcessMsg.socketSend(ProcessMsg.generateUTF8Msg(13,snake.getId()+";"+food.getId()));					
				}
			}			
		}
		
		
		//下一步是否出界
		public function outOfBounds(body:Body):Boolean{
			//按指定移动方向判断
			switch (body.getDirection())
			{
				case Body.up :
					//this.rect.y=this.rect.y-this.rect.height;
					//trace(body.getY()+"  "+body.getHeight());
					return body.getY()-body.getHeight()<0;
					break;
				case Body.down :
					//this.rect.y=this.rect.y+this.rect.height;
					return body.getY()+body.getHeight()>460;
					break;
				case Body.left :
					//this.rect.x=this.rect.x-this.rect.width;					
					return body.getX()-body.getWidth()<0;
					break;
				case Body.right :
					//this.rect.x=this.rect.x+this.rect.width;
					return body.getX()+body.getWidth()>780;
					break;
			}
			return true;
		}
		
		//当前蛇头下一步是否和其它所有蛇相撞
		public function isOverlappingSnakes(snake:Snake):Boolean{			
			for each(var otherSnake:Snake in User.getRoom().getSnakes()){
				if(this.isOverlappingSnake(snake,otherSnake)){
					return true;
				}
			}
			return false;
		}
		
		//当前蛇头下一步是否和其它玩家蛇相撞
		public function isOverlappingUsers(snake:Snake):Boolean{			
			for each(var otherSnake:Snake in User.getRoom().getUsers()){
				if(this.isOverlappingSnake(snake,otherSnake)){
					return true;
				}
			}
			return false;
		}
		
		//当前蛇头下一步是否和其它电脑蛇相撞
		public function isOverlappingComputers(snake:Snake):Boolean{			
			for each(var otherSnake:Snake in User.getRoom().getComputers()){
				if(this.isOverlappingSnake(snake,otherSnake)){
					return true;
				}
			}
			return false;
		}
		
		
		//判断一头蛇是否撞上另一头蛇
		public function isOverlappingSnake(fsnake:Snake,lsnake:Snake):Boolean{
			for each(var body:Body in lsnake.getBodys()){
				if(this.isOverlappingBody(fsnake.getHead(),body)){
					return true;
				}
			}
			//trace("----------------");
			return false;
		}
		
		//判断两个body是否重叠
		public function isOverlappingBody(fbody:Body,lbody:Body):Boolean{
			//按指定移动方向判断
			switch (fbody.getDirection())
			{
				case Body.up :
					return fbody==lbody?false:this.isOverlappingXY(fbody.getX(),fbody.getY()-fbody.getHeight(),lbody.getX(),lbody.getY());
					break;
				case Body.down :
					//this.rect.y=this.rect.y+this.rect.height;
					return fbody==lbody?false:this.isOverlappingXY(fbody.getX(),fbody.getY()+fbody.getHeight(),lbody.getX(),lbody.getY());
					break;
				case Body.left :
					//this.rect.x=this.rect.x-this.rect.width;					
					return fbody==lbody?false:this.isOverlappingXY(fbody.getX()-fbody.getWidth(),fbody.getY(),lbody.getX(),lbody.getY());					
					break;
				case Body.right :
					//this.rect.x=this.rect.x+this.rect.width;
					//trace(fbody.getX()+" "+fbody.getY()+"    "+lbody.getX()+" "+lbody.getY());
					return fbody==lbody?false:this.isOverlappingXY(fbody.getX()+fbody.getWidth(),fbody.getY(),lbody.getX(),lbody.getY());
					break;
			}
			return false;
			
		}
		
		//判断前一个坐标是否和后一个坐标相等
		public function isOverlappingXY(fx:Number,fy:Number,lx:Number,ly:Number):Boolean{
			//trace(fx+" "+fy+" "+lx+" "+ly);
			return fx==lx&&fy==ly;			
		}
		
		//玩家蛇死亡时显示
		public function snakeDeath():void{
			
			var grayTranDiv:GrayTranDiv=new GrayTranDiv();	//半透明灰色层
			User.getStage().addChildAt(grayTranDiv,User.getStage().numChildren);	//半透明灰色层
		}
		
		//停止
		public function stop():void{
			User.getStage().removeEventListener(Event.ENTER_FRAME,entherFrame);	
		}
		
		public function getNum():int{
			return this.num;
		}

	}

}